{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "\n",
    "###################################\n",
    "widthImg=540\n",
    "heightImg =640\n",
    "#####################################\n",
    "\n",
    "cap = cv2.VideoCapture(0)\n",
    "cap.set(10,150)\n",
    "\n",
    "\n",
    "def preProcessing(img):\n",
    "    imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
    "    imgBlur = cv2.GaussianBlur(imgGray,(5,5),1)\n",
    "    imgCanny = cv2.Canny(imgBlur,200,200)\n",
    "    kernel = np.ones((5,5))\n",
    "    imgDial = cv2.dilate(imgCanny,kernel,iterations=2)\n",
    "    imgThres = cv2.erode(imgDial,kernel,iterations=1)\n",
    "    return imgThres\n",
    "\n",
    "def getContours(img):\n",
    "    biggest = np.array([])\n",
    "    maxArea = 0\n",
    "    contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)\n",
    "    for cnt in contours:\n",
    "        area = cv2.contourArea(cnt)\n",
    "        if area>5000:\n",
    "            #cv2.drawContours(imgContour, cnt, -1, (255, 0, 0), 3)\n",
    "            peri = cv2.arcLength(cnt,True)\n",
    "            approx = cv2.approxPolyDP(cnt,0.02*peri,True)\n",
    "            if area >maxArea and len(approx) == 4:\n",
    "                biggest = approx\n",
    "                maxArea = area\n",
    "    cv2.drawContours(imgContour, biggest, -1, (255, 0, 0), 20)\n",
    "    return biggest\n",
    "\n",
    "def reorder (myPoints):\n",
    "    myPoints = myPoints.reshape((4,2))\n",
    "    myPointsNew = np.zeros((4,1,2),np.int32)\n",
    "    add = myPoints.sum(1)\n",
    "    #print(\"add\", add)\n",
    "    myPointsNew[0] = myPoints[np.argmin(add)]\n",
    "    myPointsNew[3] = myPoints[np.argmax(add)]\n",
    "    diff = np.diff(myPoints,axis=1)\n",
    "    myPointsNew[1]= myPoints[np.argmin(diff)]\n",
    "    myPointsNew[2] = myPoints[np.argmax(diff)]\n",
    "    #print(\"NewPoints\",myPointsNew)\n",
    "    return myPointsNew\n",
    "\n",
    "def getWarp(img,biggest):\n",
    "    biggest = reorder(biggest)\n",
    "    pts1 = np.float32(biggest)\n",
    "    pts2 = np.float32([[0, 0], [widthImg, 0], [0, heightImg], [widthImg, heightImg]])\n",
    "    matrix = cv2.getPerspectiveTransform(pts1, pts2)\n",
    "    imgOutput = cv2.warpPerspective(img, matrix, (widthImg, heightImg))\n",
    "\n",
    "    imgCropped = imgOutput[20:imgOutput.shape[0]-20,20:imgOutput.shape[1]-20]\n",
    "    imgCropped = cv2.resize(imgCropped,(widthImg,heightImg))\n",
    "\n",
    "    return imgCropped\n",
    "\n",
    "\n",
    "def stackImages(scale,imgArray):\n",
    "    rows = len(imgArray)\n",
    "    cols = len(imgArray[0])\n",
    "    rowsAvailable = isinstance(imgArray[0], list)\n",
    "    width = imgArray[0][0].shape[1]\n",
    "    height = imgArray[0][0].shape[0]\n",
    "    if rowsAvailable:\n",
    "        for x in range ( 0, rows):\n",
    "            for y in range(0, cols):\n",
    "                if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:\n",
    "                    imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)\n",
    "                else:\n",
    "                    imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)\n",
    "                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)\n",
    "        imageBlank = np.zeros((height, width, 3), np.uint8)\n",
    "        hor = [imageBlank]*rows\n",
    "        hor_con = [imageBlank]*rows\n",
    "        for x in range(0, rows):\n",
    "            hor[x] = np.hstack(imgArray[x])\n",
    "        ver = np.vstack(hor)\n",
    "    else:\n",
    "        for x in range(0, rows):\n",
    "            if imgArray[x].shape[:2] == imgArray[0].shape[:2]:\n",
    "                imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)\n",
    "            else:\n",
    "                imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)\n",
    "            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)\n",
    "        hor= np.hstack(imgArray)\n",
    "        ver = hor\n",
    "    return ver\n",
    "\n",
    "while True:\n",
    "    success, img = cap.read()\n",
    "    img = cv2.resize(img,(widthImg,heightImg))\n",
    "    imgContour = img.copy()\n",
    "\n",
    "    imgThres = preProcessing(img)\n",
    "    biggest = getContours(imgThres)\n",
    "    if biggest.size !=0:\n",
    "        imgWarped=getWarp(img,biggest)\n",
    "        # imageArray = ([img,imgThres],\n",
    "        #           [imgContour,imgWarped])\n",
    "        imageArray = ([imgContour, imgWarped])\n",
    "        cv2.imshow(\"ImageWarped\", imgWarped)\n",
    "    else:\n",
    "        # imageArray = ([img, imgThres],\n",
    "        #               [img, img])\n",
    "        imageArray = ([imgContour, img])\n",
    "\n",
    "    stackedImages = stackImages(0.6,imageArray)\n",
    "    cv2.imshow(\"WorkFlow\", stackedImages)\n",
    "\n",
    "    if cv2.waitKey(1) & 0xFF == ord('q'):\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
